package com.kanche.bigbaby.collection;


import org.joda.time.DateTime;
import org.joda.time.Years;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.ocpsoft.prettytime.PrettyTime;

import java.util.Date;

/**
 * Created by nealmi on 6/11/14.
 */
public class DateUtils {
    public static final String YEAR_2_DAY = "yyyy-MM-dd";
    public static final String YEAR_2_MONTH_CN = "yyyy年MM月";
    public static final String FULL_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    public static final String YEAR_2_MONTH = "yyyy-MM";
    private static final String YEAR = "yyyy";

    public static String format(int year, int month, int day) {
        return new DateTime(year, month, day, 0, 0, 0, 0).toString(YEAR_2_MONTH);
    }

    /**
     * @param value
     * @return int[5]{year, month, day,hour,minute}
     */
    public static int[] formatToArray(String value) {

        DateTime dateTime = new DateTime(value);
        return new int[]{dateTime.getYear(), dateTime.getMonthOfYear() - 1, dateTime.getDayOfMonth(), dateTime.getHourOfDay(), dateTime.getMinuteOfHour()};
    }

    /**
     * 格式yyyy-MM-dd HH:mm:ss to ISO
     */
    public static String formatTime(String value) {
        if (!StringUtils.hasText(value)) return "";
        DateTimeFormatter format = DateTimeFormat.forPattern(FULL_DATE_TIME);
        DateTime dateTime = DateTime.parse(value, format);
        return dateTime.toDateTimeISO().toString();
    }

    public static String formatToYearMonth(String value) {
        if (!StringUtils.hasText(value)) return "";
        return new DateTime(value).toString(YEAR_2_MONTH);
    }

    public static String formatToYearMonthDay(String value) {
        if (!StringUtils.hasText(value)) return "";
        return new DateTime(value).toString(YEAR_2_DAY);
    }

    public static String formatToYearMonthCN(String value) {
        if (!StringUtils.hasText(value)) return "";
        return new DateTime(value).toString(YEAR_2_MONTH_CN);
    }


    public static String formatToYear(String value) {
        if (!StringUtils.hasText(value)) return "";
        return new DateTime(value).toString(YEAR);
    }

    public static String formatISO8601(String value) {
        if (!StringUtils.hasText(value)) return "";

        return new DateTime(value).toDateTimeISO().toString();
    }

    public static String formatISO8601(int year, int month, int day) {
        return new DateTime(year, month, day, 0, 0, 0, 0).toDateTimeISO().toString();
    }

    public static String formatISO8601New(int year, int month, int day, int hour, int minute) {
        return new DateTime(year, month, day, hour, minute, 0, 0).toDateTimeISO().toString();
    }

    public static String calculateInspectionDateByRegistration(String date8601) {
        DateTime registrationDate = new DateTime(date8601);
        DateTime now = DateTime.now();
        DateTime sep1st2010 = new DateTime(2010, 9, 1, 0, 0, 0);
        int years = Years.yearsBetween(registrationDate, now).getYears();
        DateTime inspectionDate;
        if (years > 6) {
            inspectionDate = registrationDate.plusYears(years + 1);
        } else {
            if (registrationDate.isBefore(sep1st2010)) {
                int times = (years / 2) + 1;
                inspectionDate = registrationDate.plusYears(times * 2);
            } else {
                inspectionDate = registrationDate.plusYears(6);
            }
        }
        return inspectionDate.toDateTimeISO().toString();
    }

    public static String calculateRegularInspectionDateByRegistration(String date8601) {
        DateTime registrationDate = new DateTime(date8601);
        DateTime now = DateTime.now();
        DateTime sep1st2010 = new DateTime(2010, 9, 1, 0, 0, 0);
        int years = Years.yearsBetween(registrationDate, now).getYears();
        DateTime inspectionDate;
        if (years > 6) {
            inspectionDate = registrationDate.plusYears(years + 1);
        } else {
            int times = (years / 2) + 1;
            inspectionDate = registrationDate.plusYears(times * 2);
        }
        return inspectionDate.toDateTimeISO().toString();
    }

    public static Date parseToDate(String ct) {
        return new DateTime(ct).toDate();
    }

    public static String now() {
        return new DateTime().toDateTimeISO().toString();
    }

    public static long nowMillis() {
        return new DateTime().getMillis();
    }

    public static long getInspectionDateLimitation() {
        return new DateTime().plusYears(6).getMillis();
    }

    public static long getRegistrationDateLimitation() {
        return nowMillis();
    }

    public static long getInsuranceLimitation() {
        return new DateTime().plusYears(1).getMillis();
    }

    public static String formatFullDateTime(String value) {
        if (!StringUtils.hasText(value)) return "";
        return new DateTime(value).toString(FULL_DATE_TIME);
    }

    public static String formatPrettyTime(String ct) {
        DateTime dt = new DateTime(ct);
        DateTime aWeekAgo = new DateTime().minusDays(7);
        if (dt.isAfter(aWeekAgo)) {
            PrettyTime prettyTime = new PrettyTime();
            return prettyTime.format(dt.toDate());
        }
        return formatToYearMonthDay(ct);
    }

    public static String getBeforeDateSinceNow(int years) {
        return new DateTime().minusYears(years).toString(YEAR_2_DAY);
    }

    public static long daysLeft(String end) {
        DateTime dt = new DateTime(end);
        final long ONE_DAY = 24 * 60 * 60 * 1000L;
        long period = dt.toDate().getTime() - new Date().getTime();
        long days = period / ONE_DAY;
        long mod = period % ONE_DAY;
        if (mod != 0) {
            days += 1;
        }
        return days;
    }

    public static long daysRight(String end) {
        DateTime dt = new DateTime(end);
        final long ONE_DAY = 24 * 60 * 60 * 1000L;
        long period = new Date().getTime() - dt.toDate().getTime();
        long days = period / ONE_DAY;
        long mod = period % ONE_DAY;
//        if (mod != 0) {
//            days += 1;
//        }
        return days;
    }
}
